#pragma once
#include <cliext/algorithm>
#include <cliext/vector>

#include "BVHHandle.h"

namespace DLLx {

	ref class CTriangle {
public:
	CTriangle() { }
	CTriangle(const unsigned int v0, const unsigned int v1, const unsigned int v2) {
		v[0] = v0;
		v[1] = v1;
		v[2] = v2;
	}

	BBox WorldBound(const Point *verts)  {
		const Point &p0 = verts[v[0]];
		const Point &p1 = verts[v[1]];
		const Point &p2 = verts[v[2]];

		return Union(BBox(p0, p1), p2);
	}

	float Area(const Point *verts)  {
		const Point &p0 = verts[v[0]];
		const Point &p1 = verts[v[1]];
		const Point &p2 = verts[v[2]];

		return 0.5f * Cross(p1 - p0, p2 - p0).Length();
	}

	void Sample(const Point *verts, const float u0,
		const float u1, Point *p)  {
		float b0, b1;
		UniformSampleTriangle(u0, u1, &b0, &b1);

		// Get triangle vertices in _p1_, _p2_, and _p3_
		const Point &p0 = verts[v[0]];
		const Point &p1 = verts[v[1]];
		const Point &p2 = verts[v[2]];
		const float b2 = 1.f - b0 - b1;
		*p = b0 * p0 + b1 * p1 + b2 * p2;
	}

	void InterpolateNormal(Normal *norm, const Normal *normals, const float b1, const float b2) {
		const float b0 = 1.f - b1 - b2;
		*norm = Normalize(b0 * normals[v[0]] + b1 * normals[v[1]] + b2 * normals[v[2]]);
	}

	array<unsigned int>^ v;
};

	ref class BvhAccellerator
	{
	public:
			BvhAccellerator(TriangleData^ data, const unsigned int treeType, const int csamples, const int icost,
				const int tcost, const float ebonus) :treeType(treeType),costSamples(csamples),isectCost(icost), traversalCost(tcost), emptyBonus(ebonus)
			{

			}

	private:
			unsigned int treeType;
			int costSamples, isectCost, traversalCost;
			float emptyBonus;
			unsigned int nPrims;
			unsigned int nNodes;

			array<BVHAccelNode^>^ bvhTree;
	};
}

